﻿using System;
using System.Windows;
using System.Windows.Controls;
using FXSStation.Modules.SharedInfrastructureModule.Extentions.TileView;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Regions;
using FXSStation.Modules.SharedInfrastructureModule.Events;
using Microsoft.Practices.Composite.Presentation.Events;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Common;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Accounts;
using System.ComponentModel;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Reports;
using System.Collections.ObjectModel;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Orders;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using FXSStation.Modules.ReportModule.Views.MainReportView;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using UIComposition.Infrastructure;

namespace FXSStation.Modules.Views.MainReportView.ReportModule.Views.MainReportView
{
    /// <summary>
    /// Interaction logic for MainReportView.xaml
    /// </summary>
    public partial class MainReportView : UserControl, ITileViewItem, IMainReportView, IReportRepository, INotifyPropertyChanged
    {
        public IEventAggregator _eventAggregator { get; set; }
        public SubscriptionToken _subscriptionToken { get; set; }
        private BackgroundWorker _workerReport = new BackgroundWorker();

        public MainReportView()
        {
            InitializeComponent();
            this.Title = "Reports";

            // hack to handle the closing event of the main window:
            Application.Current.MainWindow.Closing+=new CancelEventHandler(OnMainWindowClosing);
            _workerReport.DoWork += new DoWorkEventHandler(PrecacheReportsAsync);
            FileInfo fi = new FileInfo(RXSStationFileNames.ImagesPath + "Reports.png");
            if (fi.Exists)
            {
                this.Icon = new BitmapImage(new Uri(fi.FullName, UriKind.RelativeOrAbsolute));
            }
            this.Reports = new ObservableCollection<Report>();
            this.DataContext = this;
        }

        void PrecacheReportsAsync(object sender, DoWorkEventArgs e)
        {
            this.SessionReport = CreateSessionReport(this.CurrentAccount.CurrentSession);
            this.AccountReport = CreateFullReportFor(this.CurrentAccount);
            this.ComparisonReport = new ComparisonReport();
        }

        void OnMainWindowClosing(object sender, CancelEventArgs e)
        {
            // getting exception when serializing/deserializing Reports async
            // removing this for now
            //_workerSerialize.RunWorkerAsync();
        }
        public MainReportView(IEventAggregator eventAggregator, IRegionManager regionManager)
            : this()
        {
            _eventAggregator = eventAggregator;

            // Subscribing for events :

            SimulationStartedEvent simulationStartedEvent = _eventAggregator.GetEvent<SimulationStartedEvent>();
            if (_subscriptionToken != null)
            {
                simulationStartedEvent.Unsubscribe(_subscriptionToken);
            }

            _subscriptionToken = simulationStartedEvent.Subscribe(OnSimulationStarted, ThreadOption.UIThread, false);

        }

        private void OnSimulationStarted(Simulation simulation)
        {
            this.CurrentAccount = simulation.Account;
            _workerReport.RunWorkerAsync();
        }


        #region ITileViewItem Members

        public string Title { get; set; }

        public object Icon { get; set; }

        private bool _isReady;
        public bool IsReady
        {
            get { return _isReady; }
            set
            {
                _isReady = value;
            }
        }

        #endregion

        #region IMainReportView Members

        private Account _currentAccout;
        public Account CurrentAccount
        {
            get
            {
                return _currentAccout;
            }
            set
            {
                if (_currentAccout != value)
                {
                    _currentAccout = value;
                    RaisePropertyChanged("CurrentAccount");
                    if (_currentAccout != null)
                    {
                        this.IsReady = true;
                        RaisePropertyChanged("IsReady");
                    }
                    else
                    {
                        this.IsReady = false;
                        RaisePropertyChanged("IsReady");
                    }
                }
            }
        }

        private ObservableCollection<Report> _reports;
        public ObservableCollection<Report> Reports
        {
            get
            {
                return _reports;
            }
            set
            {
                if (_reports != value)
                {
                    _reports = value;
                }
            }
        }

        public Report CreateSessionReport(Session session)
        {
            Report report = new Report(ReportType.Session);
            report.Account = this.CurrentAccount;
            report.Currency = session.CurrencySymbol;
            report.StartDate = session.TimeStampStart;
            report.EndDate = session.TimeStampEnd;
            report.Orders = session.ClosedOrders;
            report.Profit = CalculateProfit(report.Orders);
            //this.Reports.Add(report);
            return report;
        }

        public Report CreateFullReport()
        {
            // not implemented
            return null;
        }

        public ObservableCollection<Report> CreateFullReportFor(Account account)
        {
            if (account == null)
            {
                return new ObservableCollection<Report>();
            }
            ObservableCollection<Report> reports = new ObservableCollection<Report>();
            foreach (Session session in account.Sessions)
                reports.Insert(0,CreateSessionReport(session));

            return reports;
        }

        public ComparisonReport CreateComparisonReport(Account account1, Account account2)
        {
            ComparisonReport report = new ComparisonReport(account1, account2);
            report.PrimaryReports = CreateFullReportFor(report.Account);
            report.SecondaryReports = CreateFullReportFor(report.SecondaryAccount);
            return report;
        }

        private decimal CalculateProfit(ObservableCollection<OrderBase> orders)
        {
            decimal profit = 0;
            foreach (OrderBase order in orders)
                profit += order.Profit;

            return profit;
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region IReportRepository Members
        private Report _sessionReport;
        public Report SessionReport
        {
            get { return _sessionReport; }
            set
            {
                _sessionReport = value;
                RaisePropertyChanged("SessionReport");
            }
        }

        private ObservableCollection<Report> _accountReport;

        public ObservableCollection<Report> AccountReport
        {
            get
            {
                return _accountReport;
            }
            set
            {
                _accountReport = value;
                RaisePropertyChanged("AccountReport");
            }
        }

        private ComparisonReport _comparisonReport;

        public ComparisonReport ComparisonReport
        {
            get { return _comparisonReport; }
            set
            {
                _comparisonReport = value;
                RaisePropertyChanged("ComparisonReport");
            }
        }
        #endregion
    }
}

